package com.ziyueyuwen.xiniao.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ziyueyuwen.xiniao.base.exception.nullpoint.UserNotExistException;
import com.ziyueyuwen.xiniao.bean.ZyClassInfo;
import com.ziyueyuwen.xiniao.bean.ZyClassUser;
import com.ziyueyuwen.xiniao.bean.ZyProductInfo;
import com.ziyueyuwen.xiniao.bean.ZyUser;
import com.ziyueyuwen.xiniao.bean.vo.ZyClassUserVO;
import com.ziyueyuwen.xiniao.dao.*;
import com.ziyueyuwen.xiniao.enums.ClassUserTypeEnum;
import com.ziyueyuwen.xiniao.service.ClassUserService;
import com.ziyueyuwen.xiniao.service.LessonUserService;
import com.ziyueyuwen.xiniao.service.baseservice.product.ProductInfoBaseService;
import com.ziyueyuwen.xiniao.util.EEOUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wancheng  on 2018/12/18.
 */
@Service
public class ClassUserServiceImpl implements ClassUserService {

    private final Integer EEO_STUDENT_IDENTITY = 1;

    @Autowired
    ZyClassUserMapper zyClassUserMapper;
    @Autowired
    ZyUserMapper zyUserMapper;
    @Autowired
    ZyClassInfoMapper zyClassInfoMapper;
    @Autowired
    ZyClassLessonUserMapper zyClassLessonUserMapper;
    @Autowired
    ProductInfoBaseService productInfoBaseService;
    @Autowired
    LessonUserService lessonUserService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrDeleteStudent(Integer classId, List<String> studentAccount) throws Exception {
        ZyClassInfo zyClassInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        ZyClassUser param = new ZyClassUser();
        param.setClassId(classId);
        param.setUserType(ClassUserTypeEnum.STUDENT);
        List<ZyClassUser> zyClassUsers = zyClassUserMapper.select(param);
        //原来班级存在的学生
        List<String> originalAccounts = zyClassUsers.stream().map(ZyClassUser::getUserAccount).collect(Collectors.toList());
        //eeo需要删除的学生
        List<String> eeoNeedDelete = originalAccounts.stream().filter(d -> !studentAccount.contains(d)).collect(Collectors.toList());
        //eeo需要添加的学生
        List<String> eeoNeedInsert = studentAccount.stream().filter(i -> !originalAccounts.contains(i)).collect(Collectors.toList());
        //删除学生
        this.deleteStudent(classId, eeoNeedDelete);
        //添加学生并同步eeo
        this.addStudent(classId, eeoNeedInsert);
        //同步eeo--删除学生
        if (CollectionUtils.isNotEmpty(eeoNeedDelete)) {
            EEOUtil.deleteCourseStudentMultiple(zyClassInfo.getEeoCourseId(), eeoNeedDelete, EEO_STUDENT_IDENTITY);
        }
        //同步eeo--添加学生
        if (CollectionUtils.isNotEmpty(eeoNeedInsert)) {
            this.addEEOStudent(zyClassInfo, eeoNeedInsert);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addStudent(Integer classId, List<String> eeoNeedInsert) throws Exception {
        if (CollectionUtils.isEmpty(eeoNeedInsert)) {
            return;
        }
        if (CollectionUtils.isNotEmpty(eeoNeedInsert)) {
            List<ZyClassUser> list = new ArrayList<>();
            Date date = new Date();
            for (String account : eeoNeedInsert) {
                ZyClassUser zyClassUser = new ZyClassUser();
                zyClassUser.setClassId(classId);
                zyClassUser.setUserAccount(account);
                zyClassUser.setCreateTime(date);
                zyClassUser.setUserType(ClassUserTypeEnum.STUDENT);
                list.add(zyClassUser);
            }
            zyClassUserMapper.insertBatch(list);
            //此处添加学生和课节绑定关系
            lessonUserService.addLessonStudent(classId, eeoNeedInsert);
        }

    }

    private void addEEOStudent(ZyClassInfo zyClassInfo, List<String> eeoNeedInsert) throws Exception {
        //eeo 相关
        List<ZyUser> students = zyUserMapper.getByUserAccountList(eeoNeedInsert);
        Map<String, ZyUser> studentsMap = students.stream().collect(Collectors.toMap(ZyUser::getUserAccount, u -> u));
        JSONArray jsonArray = new JSONArray();
        eeoNeedInsert.forEach(
                s -> {
                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("account", s);
                    jsonObject.put("name", studentsMap.get(s).getUserName());
                    jsonArray.add(jsonObject);
                }
        );
        EEOUtil.addCourseStudentMultiple(jsonArray, zyClassInfo.getEeoCourseId(), EEO_STUDENT_IDENTITY);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addStudentOne(Integer classId, String studentAccount) throws Exception {
        List<String> needInsert = new ArrayList<>();
        needInsert.add(studentAccount);
        this.addStudent(classId, needInsert);
        ZyClassInfo zyClassInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        if (CollectionUtils.isNotEmpty(needInsert)) {
            if (CollectionUtils.isNotEmpty(needInsert)) {
                this.addEEOStudent(zyClassInfo, needInsert);
            }
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteStudent(Integer classId, List<String> eeoNeedDelete) {
        if (CollectionUtils.isEmpty(eeoNeedDelete)) {
            return;
        }
        if (CollectionUtils.isNotEmpty(eeoNeedDelete)) {
            for (String d : eeoNeedDelete) {
                ZyClassUser deleteUser = new ZyClassUser();
                deleteUser.setUserType(ClassUserTypeEnum.STUDENT);
                deleteUser.setClassId(classId);
                deleteUser.setUserAccount(d);
                zyClassUserMapper.delete(deleteUser);
            }
            //此处删除学生和课节绑定信息
            lessonUserService.deleteClassLessonStudent(classId, eeoNeedDelete);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addTeacher(Integer classId, String teacherAccount) {
        Date date = new Date();
        ZyClassUser param = new ZyClassUser();
        param.setClassId(classId);
        param.setUserAccount(teacherAccount);
        param.setUserType(ClassUserTypeEnum.TEACHER);
        ZyClassUser ifExist = zyClassUserMapper.selectOne(param);
        if (ifExist != null) {
            return;
        }
        ZyClassUser zyClassUser = new ZyClassUser();
        zyClassUser.setClassId(classId);
        zyClassUser.setUserAccount(teacherAccount);
        zyClassUser.setCreateTime(date);
        zyClassUser.setUserType(ClassUserTypeEnum.TEACHER);
        zyClassUserMapper.insertSelective(zyClassUser);
        ZyClassInfo classInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        EEOUtil.modifyCourseTeacher(classInfo.getEeoCourseId(), teacherAccount);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addMaster(Integer classId, String masterAccount) {
        Date date = new Date();
        ZyClassUser param = new ZyClassUser();
        param.setClassId(classId);
        param.setUserAccount(masterAccount);
        param.setUserType(ClassUserTypeEnum.MASTER);
        ZyClassUser ifExist = zyClassUserMapper.selectOne(param);
        if (ifExist != null) {
            return;
        }
        ZyClassUser zyClassUser = new ZyClassUser();
        zyClassUser.setClassId(classId);
        zyClassUser.setUserAccount(masterAccount);
        zyClassUser.setCreateTime(date);
        zyClassUser.setUserType(ClassUserTypeEnum.MASTER);
        zyClassUserMapper.insertSelective(zyClassUser);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateTeacher(Integer classId, String teacherAccount) {
        if (StringUtils.isBlank(teacherAccount)) {
            return;
        }
        Date date = new Date();
        zyClassUserMapper.deleteByClassId(classId, ClassUserTypeEnum.TEACHER);
        ZyClassUser zyClassUser = new ZyClassUser();
        zyClassUser.setClassId(classId);
        zyClassUser.setUserAccount(teacherAccount);
        zyClassUser.setCreateTime(date);
        zyClassUser.setUserType(ClassUserTypeEnum.TEACHER);
        zyClassUserMapper.insertSelective(zyClassUser);
        zyClassLessonUserMapper.updateTeacherWhileLessonNotStart(classId, teacherAccount);
        //eeo
        ZyClassInfo classInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        EEOUtil.modifyCourseTeacher(classInfo.getEeoCourseId(), teacherAccount);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateMaster(Integer classId, String masterAccount) throws Exception {
        if (StringUtils.isBlank(masterAccount)) {
            return;
        }
        Date date = new Date();
        zyClassUserMapper.deleteByClassId(classId, ClassUserTypeEnum.MASTER);
        ZyClassUser zyClassUser = new ZyClassUser();
        zyClassUser.setClassId(classId);
        zyClassUser.setUserAccount(masterAccount);
        zyClassUser.setCreateTime(date);
        zyClassUser.setUserType(ClassUserTypeEnum.MASTER);
        zyClassUserMapper.insertSelective(zyClassUser);
        ZyClassInfo classInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        EEOUtil.editCourse(null, null, classInfo.getEeoCourseId(), masterAccount);
    }

    @Override
    public ZyClassUserVO getTeacher(Integer lessonId) {

        return zyClassUserMapper.getTeacherByLessonId(lessonId);
    }

    @Override
    public ZyClassUserVO getTeacherByClassId(Integer classId) {
        List<ZyClassUserVO> res = zyClassUserMapper.getUser(classId, ClassUserTypeEnum.TEACHER);
        if (!CollectionUtils.isEmpty(res)) {
            return res.get(0);
        }
        return null;
    }

    @Override
    public ZyClassUserVO getMasterByClassId(Integer classId) {
        List<ZyClassUserVO> res = zyClassUserMapper.getUser(classId, ClassUserTypeEnum.MASTER);
        if (!CollectionUtils.isEmpty(res)) {
            return res.get(0);
        }
        return null;
    }

    @Override
    public List<ZyClassUserVO> getStudent(Integer classId) {
        return zyClassUserMapper.getUser(classId, ClassUserTypeEnum.STUDENT);
    }

    @Override
    public ZyClassUser getStudent(Integer classId, String userAccount) {
        ZyClassUser param = new ZyClassUser();
        param.setClassId(classId);
        param.setUserAccount(userAccount);
        param.setUserType(ClassUserTypeEnum.STUDENT);
        ZyClassUser user = zyClassUserMapper.selectOne(param);
        return user;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addClassStudentFromProduct(Integer classId, String studentAccount) throws Exception {
        ZyClassInfo classInfo = zyClassInfoMapper.selectByPrimaryKey(classId);
        if (classInfo == null) {
            throw new Exception("班级不存在");
        }
        ZyUser student = zyUserMapper.getByUserAccount(studentAccount);
        if (student == null) {
            throw new UserNotExistException(studentAccount);
        }
        ZyClassUser ifStudentExist = getStudent(classId, studentAccount);
        if (ifStudentExist != null) {
            throw new Exception("该班级已存在当前学生");
        }
        ZyProductInfo param = new ZyProductInfo();
        param.setClassId(classId);
        ZyProductInfo product = productInfoBaseService.selectOneByZyCommodityInfo(param);
        if (product == null) {
            throw new Exception("班级对应的商品不存在");
        }
        if (!product.getIfUpperShelf()) {
            throw new Exception("班级对应的商品已下架");
        }
        Integer studentCount = zyClassUserMapper.getStudentCount(classId);
        if (studentCount >= classInfo.getStudentNum()) {
            throw new Exception("已经超出该班级的最大人数");
        }
        this.addStudentOne(classId, studentAccount);
    }


}
